package com.common.base.utils

import android.content.ClipData
import android.content.ClipboardManager
import android.content.ContentResolver
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.graphics.Typeface
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan
import android.text.style.StyleSpan
import androidx.annotation.DrawableRes
import com.common.base.app.extras.isEmpty
import com.common.base.app.extras.isNoEmpty
import com.common.base.app.extras.yes
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.select.Elements
import java.math.BigDecimal
import java.util.Random
import java.util.regex.Pattern
import kotlin.math.floor
import kotlin.math.pow
import kotlin.math.roundToLong

object IStringUtils {
    //  随机数生成器
    private val random = Random()

    //  生成随机数的默认位数
    private const val BITS: Long = 6

    fun isEmpty(value: String?): Boolean {
        if (TextUtils.isEmpty(value) || value == "null") {
            return true
        }
        return false
    }

    fun isNoEmpty(value: String?): Boolean {
        return !isEmpty(value)
    }

    fun splitAppUrlString(value: String?, start: String, end: String? = null): String? {
        value?.let {
            if (end != null) {
                if (value.contains(start) && value.contains(end)) {
                    return value.substring(value.indexOf(start) + start.length, value.indexOf(end))
                }
            } else {
                if (value.contains(start)) {
                    return value.substring(value.indexOf(start) + start.length)
                }
            }
        }
        return null
    }

    fun splitString(value: String, end: String): String {
        return value.substring(0, value.lastIndexOf(end) + 1)
    }

    fun splitEndString(value: String, start: String): String {
        return value.substring(value.lastIndexOf(start) + 1, value.length)
    }

    /**
     * 截取字符串,从start到end
     */
    fun splitNumber(value: String, start: Int, end: Int): String {
        if (TextUtils.isEmpty(value)) return ""
        if (start < 0 || start >= value.length) {
            return ""
        }

        if (end < 0 || end > value.length) {
            return ""
        }

        return value.substring(start, end)

    }

    fun splitString(value: String?): List<String> {
        value?.let {
            if (it.contains(":")) {
                return it.split(":")
            }
        }
        return ArrayList()
    }

    fun toInt(value: Any?): Int {
        try {
            return value?.toString()?.toDouble()?.toInt() ?: 0
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return 0
    }

    fun toDouble(i: String?): Double {
        var intValue = 0.0
        if (isNoEmpty(i)) {
            i?.let {
                try {
                    intValue = it.toDouble()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        return intValue
    }

    fun toDouble2DecimalPlaces(i: String?): String {
        var intValue: Double
        var intValueStr = "0"
        if (isNoEmpty(i)) {
            i?.let {
                try {
                    intValue = it.toDouble()
                    intValueStr = BigDecimal(intValue).setScale(2, BigDecimal.ROUND_HALF_UP)
                        .toString()//两位小数（1.00）
                    if (intValue <= 0) intValueStr = "0"
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        return intValueStr.replace(".00", "")
    }

    fun toFloat(i: String?): Float {
        var intValue = 0f
        if (isNoEmpty(i)) {
            i?.let {
                try {
                    intValue = it.toFloat()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        return intValue
    }

    fun toLong(i: String?): Long {
        var intValue = 0L
        if (isNoEmpty(i)) {
            i?.let {
                try {
                    intValue = it.toLong()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        return intValue
    }

    /**
     *   返回安全字符串
     * */
    fun safeString(str: String?): String {
        return safeString(str, "")
    }

    fun safeString(str: Long?): String {
        return str?.toString() ?: ""
    }

    fun safeString(str: String?, defaultStr: String): String {
        if (null == str || str.isEmpty())
            return defaultStr

        return str
    }


    /**
     *  返回安全HTML字符串
     * */
    fun safeHtml(text: String?): String {
        if (text.isNullOrEmpty())
            return ""

        val buffer = StringBuffer()
        for (c in text) {
            when (c) {
                '<' -> {
                    buffer.append("&lt;")
                }
                '>' -> {
                    buffer.append("&gt;")
                }
                '&' -> {
                    buffer.append("&amp;")
                }
                '"' -> {
                    buffer.append("&quot;")
                }
                else -> {
                    buffer.append(c)
                }
            }
        }
        return buffer.toString()
    }

    /**
     * 包含换行
     */
    fun containsChangeLine(str: String): Boolean {
        if (str.isNullOrEmpty()) {
            return false
        }
        return str.contains("\n")
    }

    /**
     * 整型字符串
     */
    fun isInteger(str: String): Boolean {
        val pattern = Pattern.compile("^[-\\+]?[\\d]*$")
        return pattern.matcher(str).matches()
    }

    /**
     * 将string类型颜色
     */
    fun parseColor(colorStr: String?, def: String = "#FF4A4A"): Int {
        return try {
            return Color.parseColor(colorStr)
        } catch (e: Exception) {
            Color.parseColor(def)
        }
    }
    /**
     * 将string类型颜色
     */
    fun parseColor(colorStr: String?, colorDefault: Int): Int {
        return try {
            if (colorStr?.length == 4) {
                Color.parseColor(colorStr + colorStr.substring(1))
            } else if (colorStr?.isNotEmpty() == true) {
                Color.parseColor(colorStr)
            } else {
                colorDefault
            }
        } catch (e: Exception) {
            colorDefault
        }
    }

    @JvmStatic
    fun getHttp(str: String?): String? {
        var path = str
        if (path?.contains("https") == true) {
            path = path.replace("https", "http")
        }
        return path
    }

    /**
     * 对小数字符串切割
     * 1) 小数部分保留二位
     * 2) 小数部分为0,则去掉小数部分
     */
    fun splitDotString(str: String?): String {
        if (TextUtils.isEmpty(str)) return ""
        if (str?.contains(".") == true) {
            var list = str.split(".")
            if (list.size > 1) {
                var decimalStr = list[1]
                return if (decimalStr == "0" || decimalStr.startsWith("00")) {
                    list[0]
                } else {
                    list[0] + "." + decimalStr
                }
            }
        }
        return str ?: ""
    }

    fun formatNumber(x: Float, z: Int): String {
        return String.format("%." + z + "f", x)
    }

    fun formatNumber(x: Double, z: Int): String {
        return String.format("%." + z + "f", x)
    }

    fun subEndString(value: String): String {
        return value.substring(0, value.length - 2)
    }

    fun formatNumber1(num: String?): String {
        if (num.isNullOrEmpty())
            return "0.0"
        try {
            val n = num.toFloat()
            return formatNumber1(n)
        } catch (e: java.lang.Exception) {
            return "0"
        }
    }

    fun formatNumber1(num: Float): String = formatNumber(num, 1)

//    fun addExpert(subChannels: ArrayList<CmsTab>) {
//        subChannels.forEach {
//            if (it.channelId == 913L) {
//                return
//            }
//        }
//        subChannels.add(CmsTab(913L, "专家", false, 3, ""))
//    }

    fun getNCAAStr(number: String?): String {
        return when (number) {
            "1" -> "上半场"
            "2" -> "下半场"
            else -> "加时"
        }
    }

    //将整形数字转换为中文数字
    fun getNumberStr(number: Int): String {
        return getNumberStr("$number")
    }

    fun getNumberStr(number: String?): String {
        return when (number) {
            "1" -> "一"
            "2" -> "二"
            "3" -> "三"
            "4" -> "四"
            "5" -> "五"
            "6" -> "六"
            "7" -> "七"
            "8" -> "八"
            "9" -> "九"
            "10" -> "十"
            else -> "$number"
        }
    }

    //获取一个主队带标识的SpannableString
    fun getEndMinTxtHostTeamName(
        value: String?,
        length: Int = 6,
        sportType: Int,
        showBold: Boolean = true
    ): SpannableString {
        val valueStr = getShortStr(value, length)
        var allStr = valueStr
        if (sportType == 2) {
            allStr = "$valueStr(主)"
        }

        //(主)标识改变大小
        val spannableString = SpannableString(allStr)
        val relativeSizeSpan = RelativeSizeSpan(0.8f)
        spannableString.setSpan(
            relativeSizeSpan,
            valueStr.length,
            allStr.length,
            Spanned.SPAN_INCLUSIVE_EXCLUSIVE
        )

        //（主）标识改变颜色
        val foregroundColorSpan = ForegroundColorSpan(Color.parseColor("#999999"))
        spannableString.setSpan(
            foregroundColorSpan,
            valueStr.length,
            allStr.length,
            Spanned.SPAN_INCLUSIVE_EXCLUSIVE
        )

        if (showBold) {
            //队名加粗
            val boldSpan = StyleSpan(Typeface.BOLD)
            spannableString.setSpan(boldSpan, 0, valueStr.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
        }
        return spannableString
    }

    fun getExpertDiscountsInfo(discounts: String?): SpannableString {
        val allStr = "已减:$discounts" + "红钻"
        val spannableString = SpannableString(allStr)
        val discountsColorSpan = ForegroundColorSpan(Color.parseColor("#FB725B"))
        spannableString.setSpan(
            discountsColorSpan,
            3,
            allStr.length,
            Spanned.SPAN_INCLUSIVE_EXCLUSIVE
        )
        return spannableString
    }

    fun getShortStr(value: String?, length: Int): String {
        var valueStr = value ?: ""
        if (length <= 0) {
            return valueStr
        }
        if (valueStr.length >= length) {
            valueStr = valueStr.substring(0, length)
        }
        return valueStr
    }


    fun isOnlyContainCharAndNumber(content: String): Boolean {
        val regex = "^[a-zA-Z0-9\u4E00-\u9FA5]+$"
        val pattern = Pattern.compile(regex)
        val match = pattern.matcher(content)
        val b = match.matches()
        return b
    }

    //获取价格
    fun getPriceStr(price: Double): String {
        var resultPriceStr = price.toString()
        if (resultPriceStr.endsWith(".0") || resultPriceStr.endsWith(".00")) {
            resultPriceStr = "${price.toInt()}"
        }
        return resultPriceStr
    }

    /**
     * 是否包含汉字
     */
    fun isChinese(str: String): Boolean {
        for (index in str.indices) {
            if (str[index] >= 0x4E00.toChar() && str[index] <= 0x9FA5.toChar())
                return true
        }
        return false
    }

    /***
     * 封装两个表达式相加,表达式返回Float
     */
    fun addFloat(num1: Float, num2: Float): Float {
        return num1 + num2
    }


    fun List<String>.clearEmpty(): ArrayList<String> {
        val list = ArrayList<String>()
        this.forEach {
            it.isNoEmpty().yes {
                list.add(it)
            }
        }
        return list
    }

    /**
     * 设置img标签下的width为手机屏幕宽度，height自适应
     *
     * @param data html字符串
     * @return 更新宽高属性后的html字符串
     */
    fun getNewWebData(data: String): String {
        val document: Document = Jsoup.parse(data)
        val pElements: Elements = document.select("p:has(img)")
        for (pElement in pElements) {
            pElement.attr("style", "text-align:center")
            pElement.attr("max-width",  "${ViewUtils.getScreenWidth()}px")
                .attr("height", "auto")
        }

        val imgElements: Elements = document.select("img")
        for (imgElement in imgElements) {
            //重新设置宽高
            imgElement.attr("max-width", "100%")
                .attr("height", "auto")
            imgElement.attr("style", "max-width:100%;height:auto")
        }
//        Log.i("newData:", document.toString())
        return document.toString()
    }


    fun getNewContent2(htmltext: String): String? {
//        Document doc = Jsoup.parse(htmltext);
//        Elements elements = doc.getElementsByTag("img");
//        for (Element element : elements) {
//            element.attr("width", "100%")
//                    .attr("height", "auto");
//        }
//        return doc.toString();// 图片资源出问题时会无限拉长
        var newContent = ""
        if (!TextUtils.isEmpty(htmltext)) {
            newContent = htmltext.replace("<img", "<img style=\"display:        ;max-width:100%;\"")
        }
        return newContent
    }

    //系统剪贴板-复制:   s为内容
    fun copy(context: Context, s: String?) {
        if (TextUtils.isEmpty(s)) {
            ToastUtils.showToast("无可复制文本！")
            return
        }
        // 获取系统剪贴板
        val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        // 创建一个剪贴数据集，包含一个普通文本数据条目（需要复制的数据）
        val clipData = ClipData.newPlainText(null, s)
        // 把数据集设置（复制）到剪贴板
        clipboard.setPrimaryClip(clipData)
    }

    //系统剪贴板-获取:
    fun getCopy(context: Context): String? {
        // 获取系统剪贴板
        val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager

        //无数据时直接返回
        if (!clipboard.hasPrimaryClip()) {
            return ""
        }

        // 返回数据
        val clipData = clipboard.primaryClip ?: return ""
        if (clipData.itemCount > 0) {
            if (clipData.getItemAt(0) == null) {
                return ""
            }
            return if (TextUtils.isEmpty(clipData.getItemAt(0).text)) {
                ""
            } else clipData.getItemAt(0).text.toString()

            // 从数据集中获取（粘贴）第一条文本数据
        }
        return ""
    }

    /**
     * 对字符串处理:将指定位置到指定位置的字符以星号代替
     *
     * @param content 传入的字符串
     * @param begin   开始位置
     * @param end     结束位置
     * @return
     */
    fun getStarString(content: String, begin: Int, end: Int): String? {
        if (begin >= content.length || begin < 0) {
            return content
        }
        if (end >= content.length || end < 0) {
            return content
        }
        if (begin >= end) {
            return content
        }
        var starStr = ""
        for (i in begin until end) {
            starStr = "$starStr*"
        }
        return content.substring(0, begin) + starStr + content.substring(end, content.length)
    }

    /**
     * 对字符加星号处理：除前面几位和后面几位外，其他的字符以星号代替
     *
     * @param content  传入的字符串
     * @param frontNum 保留前面字符的位数
     * @param endNum   保留后面字符的位数
     * @return 带星号的字符串
     */
    fun getStarString2(content: String, frontNum: Int, endNum: Int): String? {
        if (frontNum >= content.length || frontNum < 0) {
            return content
        }
        if (endNum >= content.length || endNum < 0) {
            return content
        }
        if (frontNum + endNum >= content.length) {
            return content
        }
        var starStr = ""
        for (i in 0 until content.length - frontNum - endNum) {
            starStr = "$starStr*"
        }
        return (content.substring(0, frontNum) + starStr
                + content.substring(content.length - endNum, content.length))
    }


    /**
     * 随机取N位数
     *
     * @param
     * @return
     */
    fun getRandomListDocVo(mRandom:Int = 5,hasUppercase:Boolean = false): String {

        if (mRandom<1) return "0"

        var beforeShuffle = mutableListOf(
            "0", "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
            "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
            "w", "x", "y", "z"
        )
        val uppercaseShuffle = mutableListOf(
            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
            "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"
        )

        if (hasUppercase) {
            beforeShuffle.addAll(uppercaseShuffle)
        }
        val selected = mutableListOf<String>() // 创建空的 MutableList
        while (selected.size < mRandom) {
            val randomIndex = random.nextInt(beforeShuffle.size) // 随机生成一个索引
            val element = beforeShuffle[randomIndex] // 根据索引获取元素

            if (!selected.contains(element)) {
                selected.add(element) // 新的元素加入选中列表
            }
        }
        return selected.joinToString(separator = "")
    }

    /**
     * 生成(获得)n位随机数串
     *
     * @param n 生成随机数串的位数
     * @return 返回生成的 n为数字串
     */
    fun getNBitRandomDigit(n: Long): String? {
        var n = n
        if (n < 1) {  //  若 n小于 1，则设置为生成随机数的默认位数
            n = BITS
        }
        //  存储中间生成的数串
        val randomDigitStr = StringBuffer()
        //  生成的随机数
        var randomDigit: Long
        if (n < 18) {
            //  生成 n位随机数（-0.5避免生成的前 n均为 9最终四舍五入时（可能）超出一位数字）
            randomDigit = (random.nextDouble() * Math.pow(
                10.0,
                n.toDouble()
            ) - 0.5).roundToLong()
            randomDigitStr.append(randomDigit)
        } else {
            //  n超过 18，则通过生成多个 18位随机数连接成更长串
            var i = 0
            while (i < floor((n / 18).toDouble())) {

                //  生成 18位随机数（long最长为 19位且非所有位均为 9，所以取 18位）
                randomDigit = (random.nextDouble() * 10.0.pow(18.0) - 0.5).roundToLong()
                randomDigitStr.append(randomDigit)
                ++i
            }
        }
        //  生成的随机数串位数
        val randomDigitStrLength = randomDigitStr.length

        //  生成的随机数串位不足但是也不达 18位时，循环随机插入随机生成的[0, 9]间任意一位数
        if (randomDigitStrLength < n) {
            for (i in 0 until n - randomDigitStrLength) {
                //  生成可插入的下标位置（若位置为 randomDigitStr.length()，则是在末尾添加）
                val offset: Int =
                    random.nextInt(randomDigitStr.length + 1)
                if (offset < randomDigitStr.length) {
                    //  在 offset位置（下标）插入随机生成的[0, 9]间一位数
                    randomDigitStr.insert(
                        offset,
                        random.nextInt(10)
                    )
                } else {
                    //  在数串末尾添加[0, 9]间一位数
                    randomDigitStr.append(
                       random.nextInt(
                            10
                        )
                    )
                }
            }
        }
        return randomDigitStr.toString()
    }


    fun getNewContent(htmltext: String?): String {
//        Document doc = Jsoup.parse(htmltext);
//        Elements elements = doc.getElementsByTag("img");
//        for (Element element : elements) {
//            element.attr("width", "100%")
//                    .attr("height", "auto");
//        }
//        return doc.toString();// 图片资源出问题时会无限拉长
        var newContent = ""
        htmltext?.let {
            newContent = it.replace("<img", "<img style=\"display:        ;max-width:100%;\"")
        }
        return newContent
    }

    /**
     * 手机号中间密文
     *
     * @param phoneNo
     * @return
     */
    fun mobileCipherText(phoneNo: String): String {
        var mNameMi = ""
        if (TextUtils.isEmpty(phoneNo)) {
            return mNameMi
        }
        mNameMi = phoneNo.replace("(\\d{3})\\d{4}(\\d{4})".toRegex(), "$1****$2")
        return mNameMi
    }


    fun getResourcesUri(@DrawableRes id: Int): String {
        val resources: Resources = AppUtils.getContext().resources
        return ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                resources.getResourcePackageName(id) + "/" +
                resources.getResourceTypeName(id) + "/" +
                resources.getResourceEntryName(id)
    }
}

/**
 *将所有非数字字符替换为空字符串
 */
fun getOnlyDigits(input: String,hasDecimal:Boolean = false): String {
    var regex = Regex("[^\\d]")//只留阿拉伯数字
    if (hasDecimal) regex = Regex("[^\\d.]")//保留小数点
    return regex.replace(input, "")
}